// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// +build ignore

// syscalls_gen processes system headers and generates a mapping from system call names to numbers.
// Usage:
//   $ echo "#include <asm/unistd.h>" | x86_64-cros-linux-gnu-gcc     -E -dD - | go run syscalls_gen.go | gofmt > syscalls_amd64.go
//   $ echo "#include <asm/unistd.h>" | i686-pc-linux-gnu-gcc         -E -dD - | go run syscalls_gen.go | gofmt > syscalls_386.go
//   $ echo "#include <asm/unistd.h>" | armv7a-cros-linux-gnueabi-gcc -E -dD - | go run syscalls_gen.go | gofmt > syscalls_arm.go
package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"regexp"
)

func main() {
	type syscall struct {
		prefix string
		name   string
	}

	define := regexp.MustCompile(`^#define __([A-Z]+_)?NR_([a-z0-9_]+)`)
	undef := regexp.MustCompile(`^#undef __([A-Z]+_)?NR_([a-z0-9_]+)`)

	defined := []syscall{}
	undefed := map[syscall]bool{}

	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		line := scanner.Text()
		if match := define.FindStringSubmatch(line); match != nil {
			defined = append(defined, syscall{match[1], match[2]})
		}
		if match := undef.FindStringSubmatch(line); match != nil {
			undefed[syscall{match[1], match[2]}] = true
		}
	}
	if err := scanner.Err(); err != nil {
		log.Fatalf("Error reading standard input: %v", err)
	}

	fmt.Println("// DO NOT EDIT. Autogenerated by syscalls_gen.go")
	fmt.Println()
	fmt.Println("package seccomp")
	fmt.Println("// #include <asm/unistd.h>")
	fmt.Println("import \"C\"")
	fmt.Println("// syscallNum maps system call names to numbers.")
	fmt.Println("var syscallNum = map[string]int{")
	for _, call := range defined {
		if !undefed[call] {
			fmt.Printf("%q: C.__%sNR_%s,\n", call.prefix+call.name, call.prefix, call.name)
		}
	}
	fmt.Println("}")
}
